//
//  XLWavefromView.m
//  AudioWaveDemo
//
//  Created by ilongge on 2023/4/17.
//

#import "XLSampleDataProvider.h"
#import "XLSampleDataFilter.h"
#import "XLWavefromView.h"
#import "XLAudioSpectrumPlayer.h"
#import <QuartzCore/QuartzCore.h>
#import <AVFoundation/AVFoundation.h>

@interface XLWavefromView ()
<AVAudioPlayerDelegate>
@property (nonatomic, strong) AVAsset *asset;
@property (nonatomic, strong) XLSampleDataFilter *filter;
@property (nonatomic, strong) NSMutableArray *samples;
@property (nonatomic, strong) NSMutableArray *filteredSamples;
@property (nonatomic, assign) NSInteger duration;
@property (nonatomic, strong) CAShapeLayer *waveLayer;
@property (nonatomic, strong) XLAudioSpectrumPlayer *player;
@end

@implementation XLWavefromView

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        self.waveLayer = [[CAShapeLayer alloc] init];
        self.filter = [[XLSampleDataFilter alloc] init];
        self.samples = [NSMutableArray array];
        self.filteredSamples = [NSMutableArray array];
        self.player = [[XLAudioSpectrumPlayer alloc] init];
        [self.layer addSublayer:self.waveLayer];
    }
    return self;
}
- (void)setAudioUrl:(NSURL *)audioUrl
{
    if (_audioUrl != audioUrl){
        _audioUrl = audioUrl;
        AVAsset *asset = [AVAsset assetWithURL:_audioUrl];
        self.asset = asset;
    }
}
- (void)setAsset:(AVAsset *)asset
{
    if (_asset != asset){
        _asset = asset;
    }
}

- (void)startShowWace
{
    CGFloat height = self.frame.size.height;
    CGSize size = self.frame.size;
    
    //    [XLSampleDataProvider loadAudioSampleFromAsset:self.asset
    //                                   completionBlock:^(NSData *sampleData, NSInteger duration) {
    //        self.filter = [[XLSampleDataFilter alloc] initWithData:sampleData];
    //        self.duration = duration;
    //        self.samples = [self.filter filteredSamplesForBinSize:441 maxHeight:self.bounds.size.height];
    //        self.contentSize = CGSizeMake(self.samples.count, self.bounds.size.height);
    //        self.filteredSamples = self.samples;
    //        [self setNeedsDisplay];
    //    }];
    NSMutableData *data = [NSMutableData data];
    [self.player play:self.audioUrl.path
          sampleBlock:^(NSData *audioData, BOOL finshed) {
        self.samples = [NSMutableArray arrayWithArray:[self.filter filteredSamplesForSampleData:audioData size:size]];
        [data appendData:audioData];
        dispatch_sync(dispatch_get_main_queue(), ^{
            //            self.contentSize = CGSizeMake(self.samples.count, self.bounds.size.height);
            self.filteredSamples = self.samples;
            [self setNeedsDisplay];
        });
        if (finshed){
            NSString *path = [NSString stringWithFormat:@"%@.dat",self.audioUrl.path];
            [data writeToFile:path atomically:YES];
        }
    }];
    
}
- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
    self.waveLayer.path = nil;
    UIBezierPath *halfPathUp = [[UIBezierPath alloc] init];
    UIBezierPath *halfPathDown = [[UIBezierPath alloc] init];
    CGFloat midY = rect.size.height / 2.0;
    [halfPathUp moveToPoint:CGPointMake(0, midY)];
    [halfPathDown moveToPoint:CGPointMake(0, midY)];
    for (NSInteger index = 0; index < self.filteredSamples.count; index++) {
        NSNumber *number = self.filteredSamples[index];
        if (isnan(number.doubleValue)){
            continue;
        }
        CGPoint upPoint = CGPointMake(index, midY - number.floatValue);
        [halfPathUp addLineToPoint:upPoint];
        CGPoint downPoint = CGPointMake(index, midY + number.floatValue);
        [halfPathDown addLineToPoint:downPoint];
        if(index == self.filteredSamples.count -1 ){
            printf("");
        }
    }
    UIBezierPath *fullPath = [UIBezierPath bezierPath];
    [fullPath appendPath:halfPathUp];
    [fullPath addLineToPoint:CGPointMake(self.filteredSamples.count, midY)];
    [fullPath appendPath:halfPathDown];
    [fullPath addLineToPoint:CGPointMake(self.filteredSamples.count, midY)];
    self.waveLayer.fillColor = self.waveColor.CGColor;
    self.waveLayer.path = fullPath.CGPath;
}
@end
